(function ($) {
	'use strict';
	var _aui = {};
	/**
	 * [nameSpace 注册命名空间]
	 * @param  {[string]} ns [成序列的命名空间，例如'aui.foo.bar']
	 * @return {[type]}    [description]
	 */
	_aui.nameSpace = function (ns) {
		var nsParts = ns.split(".");
		var root = window;
		for (var i = 0; i < nsParts.length; i++) {
			if (typeof root[nsParts[i]] == "undefined") {
				root[nsParts[i]] = {};
			}
			root = root[nsParts[i]];
		}
		return root;
	}
	/**
	 * errlog
	 */
	_aui.Config = { // 各种url
        devLogURL: 'http://www.fang.anjuke.test/ts.html?',
        logURL: '//www.fang.anjuke.com/ts.html?',
        isDev: /dev|test/.test(document.domain),
        blackList: ['BdPlayer','baiduboxapphomepagetag']
    };
    function isblack(str) {
        var i,
            reg,
            length,
            blackList = _aui.Config.blackList;
        if (typeof str !== 'string') { // 对于非字符串默认黑名单
            return true;
        }
        for (i = 0, length = blackList.length; i < length; i++) {
            reg = new RegExp(blackList[i], 'g');
            if (reg.test(str)) {
                return true;
            }
        };
    }
    function log(params) {
        var errorinfo = 'tp=error&site=kfs&msg=',
            key,
            url,
            arr = [],
            image,
            msg;
        if (typeof params === 'string') {
            msg = params;
        }
        if (typeof params === 'object') {
            for (key in params) {
                if (params.hasOwnProperty(key)) {
                    arr.push(key + ':' + encodeURIComponent(params[key]));
                }
            }
            msg = arr.join(',');
        }
        if (isblack(msg)) {
            return false;
        }
        image = new Image();
        if (_aui.Config.isDev) {
            url = _aui.Config.devLogURL + errorinfo + msg;
        } else {
            url = _aui.Config.logURL + errorinfo + msg;
        }
        image.src = url;
    }

	window.onerror = function(msg, url, line,col,obj) {
		var stack = '';
		if(obj && obj.stack){
			stack = obj.stack;
		}
		log({
			message: msg,
			url: url,
			line: line,
			col:col,
			stack:stack,
            pageUrl: location.href,
            UA: navigator.userAgent
		});
	}

	/**
	 * [inherit 方法：使得子构造函数继承父构造函数]
	 * @param  {[this]} my  [子构造函数的环境变量 this]
	 * @param  {[fn]} classParent [父构造函数]
	 * @param  {[Array]} args        [父构造函数初始化所需要的参数,如果有的话]
	 * @return {[undefined]}             [description]
	 */
	_aui.inherit = function (my, classParent, args) {
		classParent.apply(my, args || []);
		$.extend(my.constructor.prototype, classParent.prototype);
	}
	/**
	 * [Observer 简单的事件观察的构造函数]
	 * @return {[对象]}             [包含事件触发、绑定、解除绑定的方法]
	 */
	_aui.Observer = function () {
		this._ob = {};
	}
	/**
	 * [on 按照事件类型挂载回调函数]
	 * @param  {[type]}   eventNames [事件名称，可以多事件以空格分隔]
	 * @param  {Function} callback   [回调函数]
	 * @return {[type]}              [如果是单一事件则返回当前回调所在事件空间的key值，如果是多事件则是一个对象，事件名与key相对应 ]
	 */
	_aui.Observer.prototype.on = function (eventNames, callback) {
		var _events = eventNames.split(' ');
		var _eventKeys = {};
		for (var i = 0; i < _events.length; i++) {
			if (!this._ob[_events[i]]) {
				this._ob[_events[i]] = [];
			}
			var _key = this._ob[_events[i]].push(callback);
			_eventKeys[ _events[i] ] = _key - 1; // push 返回数组长度，key是现有长度减一。
		}
		return _eventKeys;
	}
	/**
	 * [off 解除绑回调函数]
	 * @param  {[string]} eventName [事件名]
	 * @param  {[array]} keys      [指定回调的 key 组成的数组，key会在绑定函数的时候（on方法）返回]
	 * @return {[type]}           [description]
	 */
	_aui.Observer.prototype.off = function (eventName, keys) {
		if (!!keys && !$.isArray(keys)) {
			keys = [keys]
		}
		if (this._ob[eventName]) {
			for (var i = 0; i < this._ob[eventName].length; i++) {
				if (!keys || $.inArray(i, keys)) {
					this._ob[eventName][i] = undefined;
				}
			}
		}
	}
	/**
	 * [trigger 事件触发]
	 * @param  {[type]} eventName [事件名]
	 * @param  {[type]} args      [希望传递给回调函数的 数组或arguments对象]
	 * @return {[type]}           [description]
	 */
	_aui.Observer.prototype.trigger = function (eventName, args) {
		var r;
		if (!this._ob[eventName]) {
			return r;
		}
		var _arg = args || [];
		for (var i = 0; this._ob[eventName] && i < this._ob[eventName].length; i++) {
			if (!this._ob[eventName][i]) {
				continue;
			}
			var _r = this._ob[eventName][i].apply(this, _arg);
			r = (r === false) ? r : _r;
		}
		return r
	}
	/**
	 * [one 只执行一次行为的绑定方法，事件执行后立即解除绑定]
	 * @param  {[string]}   eventName [事件名]
	 * @param  {Function} callback  [回调函数]
	 * @return {[type]}             [description]
	 */
	_aui.Observer.prototype.one = function (eventName, callback) {
		var self = this;
		var key = self.on(eventName, function () {
			callback.apply(this, arguments);
			self.off(eventName, key);
		});
	}
	/**
	 * [render 模板渲染，模板字符串只能用双引号，模板内的变量必须是data的属性，且值会转化为字符串或任意能转化为字符串的类型]
	 * @param  {[string]} tpl  [模板字符串]
	 * @param  {[object]} data [数据包，键值必须和模板想对应]
	 * @return {[string]}      [经过data数据渲染过后的html模板]
	 *    var tpl = '<dl><dt>{% dt %}</dt>';
	 *        tpl += '{%> if(dd){ %}';
	 *			tpl += '{%> for( var i=0; i< dd.length; i++){ %}';
	 *				tpl += '<dd><strong>{% dd[i].skill %}:</strong>{% dd[i].level %}</dd>';
	 *		 	tpl += '{%> } %}';
	 *		tpl += '{%> } %}';
	 *        tpl += '</dl>';
	 *    var da = ajk.render(tpl,{
	 *		dt:'gameLevel',
	 *		dd:[
	 *			{
	 *				skill:'Diablo',
	 *				level:70
	 *			},
	 *			{
	 *				skill:'Dota',
	 *				level:16
	 *			}
	 *		]
	 *	});
	 *    //da: '<dl><dt>gameLevel</dt><dd><strong>Diablo:</strong>70</dd><dd><strong>Dota:</strong>16</dd></dl>'
	 */
	_aui.render = function (tpl, data, op) {
		var daName = [], daVal = [], efn = [], _fnBuf,
			_op = $.extend({}, _aui.render._options, op || {});
		for (var i in data) {
			daName.push(i);
			daVal.push('data.' + i);
		}
		var _tp = tpl.replace(new RegExp(_op.open, 'g'), _op.open + _op.val);
		_fnBuf = _tp.split(new RegExp(_op.open + '|' + _op.close, 'g'));
		for (var i = 0; i < _fnBuf.length; i++) {
			if (new RegExp('^' + _op.val + _op.exp).test(_fnBuf[i])) {
				_fnBuf[i] = _fnBuf[i].replace(new RegExp('^' + _op.val + _op.exp), '');
			} else if (_fnBuf[i].length > 0) {
				if (new RegExp('^' + _op.val).test(_fnBuf[i])) {
					_fnBuf[i] = '_buf.push(' + _fnBuf[i].replace(new RegExp('^' + _op.val), '') + ');';
				} else {
					_fnBuf[i] = '_buf.push(\'' + _fnBuf[i] + '\');';
				}
			}
		}
		efn.push('(function(');
		efn.push(daName.join(','));
		efn.push('){');
		efn.push('var _buf = [];');
		efn.push(_fnBuf.join(''));
		efn.push('return _buf.join("")');
		efn.push('})(');
		efn.push(daVal.join(','));
		efn.push(')');
		return eval(efn.join(''));
	}
	_aui.render._options = {
		open : '{%',
		close: '%}',
		exp  : '>',
		val  : '='
	}
	_aui.nameSpace('XF');
	window.XF = _aui;
})(jQuery);
;(function ($) {
  $.fn.plugin=function (options) {
    var defaults={};
    var op = $.extend(defaults,options);
    var point = new BMap.Point(op.lng, op.lat);
    var map  = new BMap.Map(op.mapId);
    map.centerAndZoom(point, op.size);      
    map.enableScrollWheelZoom(true);
    var basicConfig = op.basicConfig;
    var container  = $('#'+ op.mapId);
    var item = {
      curLP     :     '.cur-loupan',
      curLPInfo :     '#curLPInfo',
      ardLP     :     '.ard-loupan',
      showLP    :     '#aroundLP',
      nailBox   :     '.nail-box',
      nailTip   :     '.nail-tip'
    };
    var basicData = {};
    var dataList = [];
    
    var base = {
      getKeys: function(config, type) {
        var arr = [];
        for(var i = 0; i < config.length; i++){
          var item = config[i].item;
          for(var j = 0; j < item.length; j++){
              arr.push(item[j].key);
          }
        }
        return arr;
      },
      clearOverLay : function(arr){
        for(var i = 0; i < arr.length; i++){
          container.find(arr[i]).remove();
        }
      },
      basic: function() {
        var keys = base.getKeys(basicConfig, 'traffic');
        var settings = {
          onSearchComplete: function(results) {
            for (var i = 0 ; i < results.length; i++) {
              var temp = [];
              for (var k = 0; k < results[i].getCurrentNumPois(); k++) {
                var item = results[i].getPoi(k);
                temp.push({
                  title: item.title,
                  address: item.address,
                  distance: item.length,
                  point: item.point,
                  type: keys[k],
                  icon: base.getFlag(basicConfig,keys[k],'icon')
                })
              }
              temp.sort(function(m,n){return m.distance - n.distance;});
              tempList.push({
                kind : base.getFlag(basicConfig,keys[i],'kind'),
                list : temp
              });
            }

            for(var j = 0; j < basicConfig.length; j++){
              var kind = basicConfig[j].type, arr = [];
              for(var l = 0; l < tempList.length; l++){
                  if(kind == tempList[l].kind){
                      arr = arr.concat(tempList[l].list);
                  }
              }
             basicData[kind] = base.cleanArr(arr);
            }

            base.reloadByType(basicConfig[0].type);
          },
          pageCapacity: 100,
        }
        var tempList = [];
        var local = new BMap.LocalSearch(map, settings);
        local.searchNearby(keys, point, 1000);
      },
      getFlag : function(zconfig,key,flag){
        var config = zconfig || basicConfig;
        for(var i = 0; i < config.length; i++){
          var item = config[i].item;
          for(var j = 0; j < item.length; j++){
            if(item[j].key==key){
              if(flag=='icon'){
                  return item[j].icon;
              }else if(flag=='kind'){
                  return item[j].kind;
              }
            }
          }
        }
      },
      cleanArr : function(a){
        var hash = {}, result = [];
        for(var i = 0; i < a.length; i++){
            var param = a[i].title + a[i].address;
            if (!hash[param]){
                hash[param] = true;
                result.push(a[i]);
            }
        }
        return result;
      },
      reloadByType: function(type) {
        var data = base.getDataByType(type);
        dataList = data;
        base.reload();
      },
      getDataByType : function(type){
        if(type!='special'){
          return basicData[type];
        }
      },
      reload : function(){
        base.clearOverLay([item.nailBox]);
        $.each(dataList,function(i,data){
            base.drawPoint(data.point,{
                icon : data.icon,
                num  : i,
                title: data.title,
            },function(){});
        });
      },
      drawPoint : function(point, data){//绘制自定义覆盖物
        var Overlay = new ComplexCustomOverlay(point, data);
        map.addOverlay(Overlay);
      },
    }
    base.basic();

    //自定义覆盖物
	// 复杂的自定义覆盖物
    function ComplexCustomOverlay(point, data){
      this._point = point;
      this.icon = data.icon;
      this.num = data.num;
      this.title = data.title;
    }
    ComplexCustomOverlay.prototype = new BMap.Overlay();
    ComplexCustomOverlay.prototype.initialize = function(map){
      this._map = map;
      var div = this._div = document.createElement("div");
      div.className = "nail-box";
      div.style.zIndex = BMap.Overlay.getZIndex(this._point.lat);
      div.setAttribute("data-address", this.title)
      div.setAttribute("data-num", this.num);
      var i = document.createElement("i");
      i.className = 'map-icon '+this.icon+'';
      div.appendChild(i);
      map.getPanes().labelPane.appendChild(div);
      
      return div;
    }
    ComplexCustomOverlay.prototype.draw = function(){
      var map = this._map;
      var pixel = map.pointToOverlayPixel(this._point);
      this._div.style.left = pixel.x - 14 + "px";
      this._div.style.top  = pixel.y - 30 + "px";
    }
  };
})(jQuery);
